package com.sanpu.kxe.rxservice.client;

import android.support.v4.util.Pair;
import android.text.TextUtils;

import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.sanpu.kxe.business.card.bean.BankInfoOutput;
import com.sanpu.kxe.business.card.bean.CardOutput;
import com.sanpu.kxe.business.card.bean.DefBankOcrOutput;
import com.sanpu.kxe.business.card.bean.DefBankOutput;
import com.sanpu.kxe.common.interfaces.CommonConfig;
import com.sanpu.kxe.common.interfaces.UrlConstants;
import com.sanpu.kxe.rxservice.BaseClient;
import com.sanpu.kxe.rxservice.MetaBean;
import com.sanpu.kxe.rxservice.RequestMap;
import com.sanpu.kxe.rxservice.interfaces.BankService;

import java.io.File;
import java.util.HashMap;
import java.util.List;

import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
import rx.Observable;
import rx.functions.Func1;

/**
 * Description：银行卡模块接口
 * Created by 薛勇军 on 2018/7/16.
 */

public class BankClient extends BaseClient {

    private static BankClient mInstance;

    public static BankClient getInstance() {
        if (mInstance == null) {
            synchronized (BankClient.class) {
                if (mInstance == null) {
                    mInstance = new BankClient();
                }
            }
        }
        return mInstance;
    }

    private BankService service;

    private BankClient() {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(UrlConstants.getBaseUrl())
                .client(client)
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .build();

        service = retrofit.create(BankService.class);
    }

    /**
     * 添加银行卡
     */
    public Observable<String> insertUrmBank(JSONObject reqData) {
        RequestMap requestMap = new RequestMap();
        requestMap.put(CommonConfig.REQDATA, new Gson().toJson(reqData));
        return callMapAfterLogin(service.insertUrmBank(requestMap.getReqParams(true)))
                .flatMap(new Func1<Pair<MetaBean, String>, Observable<String>>() {
                    @Override
                    public Observable<String> call(Pair<MetaBean, String> pair) {
                        return toObservable(pair);
                    }
                });
    }

    /**
     * 添加信用卡
     */
    public Observable<String> insertCreditBank(JSONObject reqData) {
        RequestMap requestMap = new RequestMap();
        requestMap.put(CommonConfig.REQDATA, new Gson().toJson(reqData));
        return callMapAfterLogin(service.insertCreditBank(requestMap.getReqParams(true)))
                .flatMap(new Func1<Pair<MetaBean, String>, Observable<String>>() {
                    @Override
                    public Observable<String> call(Pair<MetaBean, String> pair) {
                        return toObservable(pair);
                    }
                });
    }

    /**
     * 我的银行卡列表
     */
    public Observable<List<BankInfoOutput>> selectUrmBankPage(JSONObject reqData) {
        RequestMap requestMap = new RequestMap();
        requestMap.put(CommonConfig.REQDATA, new Gson().toJson(reqData));
        return callMapAfterLogin(service.selectUrmBankPage(requestMap.getReqParams(true)))
                .flatMap(new Func1<Pair<MetaBean, String>, Observable<List<BankInfoOutput>>>() {
                    @Override
                    public Observable<List<BankInfoOutput>> call(Pair<MetaBean, String> pair) {
                        if (pair == null) {
                            return toObservable(null);
                        }
                        List<BankInfoOutput> outputs = null;
                        if (!TextUtils.isEmpty(pair.second)) {
                            outputs = new Gson().fromJson(pair.second, new TypeToken<List<BankInfoOutput>>() {
                            }.getType());
                        }
                        return toObservable(new Pair<>(pair.first, outputs));
                    }
                });
    }

    /**
     * 获取结算卡审核状态
     */
    public Observable<DefBankOutput> getDefBankStatus() {
        return callMapAfterLogin(service.getDefBankStatus(new RequestMap().getReqParams(true)))
                .flatMap(new Func1<Pair<MetaBean, String>, Observable<DefBankOutput>>() {
                    @Override
                    public Observable<DefBankOutput> call(Pair<MetaBean, String> pair) {
                        if (pair == null) {
                            return toObservable(null);
                        }
                        DefBankOutput output = null;
                        if (!TextUtils.isEmpty(pair.second)) {
                            output = new Gson().fromJson(pair.second, new TypeToken<DefBankOutput>() {
                            }.getType());
                        }
                        return toObservable(new Pair<>(pair.first, output));
                    }
                });
    }

    /**
     * 查询银行卡信息
     */
    public Observable<CardOutput> bankInfo(JSONObject reqData) {
        RequestMap requestMap = new RequestMap();
        requestMap.put(CommonConfig.REQDATA, new Gson().toJson(reqData));
        return callMapAfterLogin(service.bankInfo(requestMap.getReqParams(true)))
                .flatMap(new Func1<Pair<MetaBean, String>, Observable<CardOutput>>() {
                    @Override
                    public Observable<CardOutput> call(Pair<MetaBean, String> pair) {
                        if (pair == null) {
                            return toObservable(null);
                        }
                        CardOutput output = null;
                        if (!TextUtils.isEmpty(pair.second)) {
                            output = new Gson().fromJson(pair.second, new TypeToken<CardOutput>() {
                            }.getType());
                        }
                        return toObservable(new Pair<>(pair.first, output));
                    }
                });
    }

    /**
     * 修改银行卡预留手机号
     */
    public Observable<String> updateBankRsdTel(JSONObject reqData) {
        RequestMap requestMap = new RequestMap();
        requestMap.put(CommonConfig.REQDATA, new Gson().toJson(reqData));
        return callMapAfterLogin(service.updateBankRsdTel(requestMap.getReqParams(true)))
                .flatMap(new Func1<Pair<MetaBean, String>, Observable<String>>() {
                    @Override
                    public Observable<String> call(Pair<MetaBean, String> pair) {
                        return toObservable(pair);
                    }
                });
    }

    /**
     * 修改默认结算卡
     */
    public Observable<String> updateDefUrmBank(JSONObject reqData, HashMap<String, File> files) {
        RequestMap requestMap = new RequestMap();
        requestMap.put(CommonConfig.REQDATA, new Gson().toJson(reqData));
        return callMapAfterLogin(service.updateDefUrmBank(requestMap.getReqParams(true), files2Parts(files)))
                .flatMap(new Func1<Pair<MetaBean, String>, Observable<String>>() {
                    @Override
                    public Observable<String> call(Pair<MetaBean, String> pair) {
                        return toObservable(pair);
                    }
                });
    }

    /**
     * 修改默认结算卡(银行卡识别和人脸对比)
     */
    public Observable<DefBankOcrOutput> ocrBankCardAndFaceMatch(HashMap<String, File> files) {
        return callMapAfterLogin(service.ocrBankCardAndFaceMatch(new RequestMap().getReqParams(true), files2Parts(files)))
                .flatMap(new Func1<Pair<MetaBean, String>, Observable<DefBankOcrOutput>>() {
                    @Override
                    public Observable<DefBankOcrOutput> call(Pair<MetaBean, String> pair) {
                        if (pair == null) {
                            return toObservable(null);
                        }
                        DefBankOcrOutput output = null;
                        if (!TextUtils.isEmpty(pair.second)) {
                            output = new Gson().fromJson(pair.second, new TypeToken<DefBankOcrOutput>() {
                            }.getType());
                        }
                        return toObservable(new Pair<>(pair.first, output));
                    }
                });
    }

    /**
     * 修改默认结算卡（鉴权）
     */
    public Observable<String> modifyDefUrmBank(JSONObject reqData) {
        RequestMap requestMap = new RequestMap();
        requestMap.put(CommonConfig.REQDATA, new Gson().toJson(reqData));
        return callMapAfterLogin(service.modifyDefUrmBank(requestMap.getReqParams(true)))
                .flatMap(new Func1<Pair<MetaBean, String>, Observable<String>>() {
                    @Override
                    public Observable<String> call(Pair<MetaBean, String> pair) {
                        return toObservable(pair);
                    }
                });
    }

    /**
     * 修改默认结算卡（无需照片和审核）
     */
    public Observable<String> modifyDefaultCard(JSONObject reqData) {
        RequestMap requestMap = new RequestMap();
        requestMap.put(CommonConfig.REQDATA, new Gson().toJson(reqData));
        return callMapAfterLogin(service.modifyDefaultCard(requestMap.getReqParams(true)))
                .flatMap(new Func1<Pair<MetaBean, String>, Observable<String>>() {
                    @Override
                    public Observable<String> call(Pair<MetaBean, String> pair) {
                        return toObservable(pair);
                    }
                });
    }

    /**
     * 银行卡解绑
     */
    public Observable<String> deleteUrmBank(JSONObject reqData) {
        RequestMap requestMap = new RequestMap();
        requestMap.put(CommonConfig.REQDATA, new Gson().toJson(reqData));
        return callMapAfterLogin(service.deleteUrmBank(requestMap.getReqParams(true)))
                .flatMap(new Func1<Pair<MetaBean, String>, Observable<String>>() {
                    @Override
                    public Observable<String> call(Pair<MetaBean, String> pair) {
                        return toObservable(pair);
                    }
                });
    }

    /**
     * 提现
     */
    public Observable<String> userWithdraw(JSONObject reqData) {
        RequestMap requestMap = new RequestMap();
        requestMap.put(CommonConfig.REQDATA, new Gson().toJson(reqData));
        return callMapAfterLogin(service.userWithdraw(requestMap.getReqParams(true)))
                .flatMap(new Func1<Pair<MetaBean, String>, Observable<String>>() {
                    @Override
                    public Observable<String> call(Pair<MetaBean, String> pair) {
                        return toObservable(pair);
                    }
                });
    }
}
